/*
 * Matthew Cramer, Jesse Martinez, Marc Mendoza 
 * CSE 325 Lab 4
 * File: IPCManager.c
 * Description: Manager that handles the Message Queue interactions and processes.  
 *              This is called from the testing interface to perform 
 *              transitions to the queues.
 *
 */
 
 #include "../QueueManager/QueueManager.h"
 #define MAX_QUEUE_SIZE 10
 
// Create Message Queue One and its head and tail ppointers
message_block one[MAX_QUEUE_SIZE];
int oneHead = -1;
int oneTail = -1;
int oneFreeHead = 0;
int oneFreeTail = MAX_QUEUE_SIZE-1;
int oneSize = 0;
 
 // Create Message Queue two and its head and tail ppointers
message_block two[MAX_QUEUE_SIZE];
int twoHead = -1;
int twoTail = -1;
int twoFreeHead = 0;
int twoFreeTail = MAX_QUEUE_SIZE-1;
int twoSize = 0;

// Create Message Queue three and its head and tail ppointers
message_block three[MAX_QUEUE_SIZE];
int threeHead = -1;
int threeTail = -1;
int threeFreeHead = 0;
int threeFreeTail = MAX_QUEUE_SIZE-1;
int threeSize = 0;

// Create Message Queue four and its head and tail ppointers
message_block four[MAX_QUEUE_SIZE];
int fourHead = -1;
int fourTail = -1;
int fourFreeHead = 0;
int fourFreeTail = MAX_QUEUE_SIZE-1;
int fourSize = 0;

// Create Message Queue five and its head and tail ppointers
message_block five[MAX_QUEUE_SIZE];
int fiveHead = -1;
int fiveTail = -1;
int fiveFreeHead = 0;
int fiveFreeTail = MAX_QUEUE_SIZE-1;
int fiveSize = 0;

// Create Message Queue Six and its head and tail ppointers
message_block six[MAX_QUEUE_SIZE];
int sixHead = -1;
int sixTail = -1;
int sixFreeHead = 0;
int sixFreeTail = MAX_QUEUE_SIZE-1;
int sixSize = 0;
 
// Create Message Queue seven and its head and tail ppointers
message_block seven[MAX_QUEUE_SIZE];
int sevenHead = -1;
int sevenTail = -1;
int sevenFreeHead = 0;
int sevenFreeTail = MAX_QUEUE_SIZE-1;
int sevenSize = 0;

// Create Message Queue eight and its head and tail ppointers
message_block eight[MAX_QUEUE_SIZE];
int eightHead = -1;
int eightTail = -1;
int eightFreeHead = 0;
int eightFreeTail = MAX_QUEUE_SIZE-1;
int eightSize = 0;

// Create Message Queue nine and its head and tail ppointers
message_block nine[MAX_QUEUE_SIZE];
int nineHead = -1;
int nineTail = -1;
int nineFreeHead = 0;
int nineFreeTail = MAX_QUEUE_SIZE-1;
int nineSize = 0;

// Create Message Queue ten and its head and tail ppointers
message_block ten[MAX_QUEUE_SIZE];
int tenHead = -1;
int tenTail = -1;
int tenFreeHead = 0;
int tenFreeTail = MAX_QUEUE_SIZE-1;
int tenSize = 0;
 
//Declared Function
void initializeQueues(int);
void clearQueues(int);
int hasMessage(int);
int isFull(int);
int Send(int, int, int);
int Retrieve(int);

  
//Initializes Free Lists for queues
void initializeQueues(int numOfQueues)
{
	if(numOfQueues > 0)
		iniFree(&oneFreeHead, &oneFreeTail, one);
	if(numOfQueues > 1)
		iniFree(&twoFreeHead, &twoFreeTail, two);
	if(numOfQueues > 2)
		iniFree(&threeFreeHead, &threeFreeTail, three);
	if(numOfQueues > 3)
		iniFree(&fourFreeHead, &fourFreeTail, four);
	if(numOfQueues > 4)
		iniFree(&fiveFreeHead, &fiveFreeTail, five);
	if(numOfQueues > 5)
		iniFree(&sixFreeHead, &sixFreeTail, six);
	if(numOfQueues > 6)
		iniFree(&sevenFreeHead, &sevenFreeTail, seven);
	if(numOfQueues > 7)
		iniFree(&eightFreeHead, &eightFreeTail, eight);
	if(numOfQueues > 8)
		iniFree(&nineFreeHead, &nineFreeTail, nine);
	if(numOfQueues > 9)
		iniFree(&tenFreeHead, &tenFreeTail, ten);
}

//Initializes Queues for testing puposes
void clearQueues(int numOfQueues)
{
	if(numOfQueues > 0)
		iniQueue(&oneHead, &oneTail, &oneFreeHead, &oneFreeTail, &oneSize);
	if(numOfQueues > 1)
		iniQueue(&twoHead, &twoTail, &twoFreeHead, &twoFreeTail, &twoSize);
	if(numOfQueues > 2)
		iniQueue(&threeHead, &threeTail, &threeFreeHead, &threeFreeTail, &threeSize);
	if(numOfQueues > 3)
		iniQueue(&fourHead, &fourTail, &fourFreeHead, &fourFreeTail, &fourSize);
	if(numOfQueues > 4)
		iniQueue(&fiveHead, &fiveTail, &fiveFreeHead, &fiveFreeTail, &fiveSize);
	if(numOfQueues > 5)
		iniQueue(&sixHead, &sixTail, &sixFreeHead, &sixFreeTail, &sixSize);
	if(numOfQueues > 6)
		iniQueue(&sevenHead, &sevenTail, &sevenFreeHead, &sevenFreeTail, &sevenSize);
	if(numOfQueues > 7)
		iniQueue(&eightHead, &eightTail, &eightFreeHead, &eightFreeTail, &eightSize);
	if(numOfQueues > 8)
		iniQueue(&nineHead, &nineTail, &nineFreeHead, &nineFreeTail, &nineSize);
	if(numOfQueues > 9)
		iniQueue(&tenHead, &tenTail, &tenFreeHead, &tenFreeTail, &tenSize);
	initializeQueues(numOfQueues);
}

//checks if queue has message
int hasMessage(int Queue)
{
	int true = 1, false = 0;
	
	if(Queue == 1)
		if(oneSize > 0)
			return true;
		else
			return false;
	else if(Queue == 2)
		if(twoSize > 0)
			return true;
		else
			return false;
	else if(Queue == 3)
		if(threeSize > 0)
			return true;
		else
			return false;
	else if(Queue == 4)
		if(fourSize > 0)
			return true;
		else
			return false;
	else if(Queue == 5)
		if(fiveSize > 0)
			return true;
		else
			return false;
	else if(Queue == 6)
		if(sixSize > 0)
			return true;
		else
			return false;
	else if(Queue == 7)
		if(sevenSize > 0)
			return true;
		else
			return false;
	else if(Queue == 8)
		if(eightSize > 0)
			return true;
		else
			return false;
	else if(Queue == 9)
		if(nineSize > 0)
			return true;
		else
			return false;
	else if(Queue == 10)
		if(tenSize > 0)
			return true;
		else
			return false;
}

//checks if queue is full
int isFull(int Queue)
{
	int true = 1, false = 0;
	
	if(Queue == 1)
		if(oneSize == 10)
			return true;
		else
			return false;
	else if(Queue == 2)
		if(twoSize == 10)
			return true;
		else
			return false;
	else if(Queue == 3)
		if(threeSize == 10)
			return true;
		else
			return false;
	else if(Queue == 4)
		if(fourSize == 10)
			return true;
		else
			return false;
	else if(Queue == 5)
		if(fiveSize == 10)
			return true;
		else
			return false;
	else if(Queue == 6)
		if(sixSize == 10)
			return true;
		else
			return false;
	else if(Queue == 7)
		if(sevenSize == 10)
			return true;
		else
			return false;
	else if(Queue == 8)
		if(eightSize == 10)
			return true;
		else
			return false;
	else if(Queue == 9)
		if(nineSize == 10)
			return true;
		else
			return false;
	else if(Queue == 10)
		if(tenSize == 10)
			return true;
		else
			return false;
}

//gets the head of the queue
int getHead(int Queue)
{
	if(Queue == 1)
		return oneHead;
	else if(Queue == 2)
		return twoHead;
	else if(Queue == 3)
		return threeHead;
	else if(Queue == 4)
		return fourHead;
	else if(Queue == 5)
		return fiveHead;
	else if(Queue == 6)
		return sixHead;
	else if(Queue == 7)
		return sevenHead;
	else if(Queue == 8)
		return eightHead;
	else if(Queue == 9)
		return nineHead;
	else if(Queue == 10)
		return tenHead;
}

//gets the tail of the queue
int getTail(int Queue)
{
	if(Queue == 1)
		return oneTail;
	else if(Queue == 2)
		return twoTail;
	else if(Queue == 3)
		return threeTail;
	else if(Queue == 4)
		return fourTail;
	else if(Queue == 5)
		return fiveTail;
	else if(Queue == 6)
		return sixTail;
	else if(Queue == 7)
		return sevenTail;
	else if(Queue == 8)
		return eightTail;
	else if(Queue == 9)
		return nineTail;
	else if(Queue == 10)
		return tenTail;
}

//gets the size of the queue
int getSizeOfQueue(int Queue)
{
	if(Queue == 1)
		return oneSize;
	else if(Queue == 2)
		return twoSize;
	else if(Queue == 3)
		return threeSize;
	else if(Queue == 4)
		return fourSize;
	else if(Queue == 5)
		return fiveSize;
	else if(Queue == 6)
		return sixSize;
	else if(Queue == 7)
		return sevenSize;
	else if(Queue == 8)
		return eightSize;
	else if(Queue == 9)
		return nineSize;
	else if(Queue == 10)
		return tenSize;
}

//Return queue to Testing Interface
message_block* getQueue(int queue)
{
    if(queue==1)
        return one;
    else if(queue==2)
        return two;
    else if(queue==3)
        return three;
    else if(queue==4)
        return four;
    else if(queue==5)
        return five;
    else if(queue==6)
        return six;
    else if(queue==7)
        return seven;
    else if(queue==8)
        return eight;
    else if(queue==9)
        return nine;
    else if(queue==10)
        return ten;
}

//Enqueues message to destination
int Send(int source, int destination, int message)
{
	//if destination is not full, enqueue new message
	if(isFull(destination) == 0)
	{
		if(destination == 1)
		{
			Enqueue(source, destination, message, &oneHead, &oneTail, &oneFreeHead, &oneFreeTail, one);
            oneSize++;
			return 0;
		}
		else if(destination == 2)
		{
			Enqueue(source, destination, message, &twoHead, &twoTail, &twoFreeHead, &twoFreeTail, two);
			twoSize++;
            return 0;
		}
		else if(destination == 3)
		{
			Enqueue(source, destination, message, &threeHead, &threeTail, &threeFreeHead, &threeFreeTail, three);
			threeSize++;
            return 0;
		}
		else if(destination == 4)
		{
			Enqueue(source, destination, message, &fourHead, &fourTail, &fourFreeHead, &fourFreeTail, four);
			fourSize++;
            return 0;
		}
		else if(destination == 5)
		{
			Enqueue(source, destination, message, &fiveHead, &fiveTail, &fiveFreeHead, &fiveFreeTail, five);
			fiveSize++;
            return 0;
		}
		else if(destination == 6)
		{
			Enqueue(source, destination, message, &sixHead, &sixTail, &sixFreeHead, &sixFreeTail, six);
			sixSize++;
            return 0;
		}
		else if(destination == 7)
		{
			Enqueue(source, destination, message, &sevenHead, &sevenTail, &sevenFreeHead, &sevenFreeTail, seven);
			sevenSize++;
            return 0;
		}
		else if(destination == 8)
		{
			Enqueue(source, destination, message, &eightHead, &eightTail, &eightFreeHead, &eightFreeTail, eight);
			eightSize++;
            return 0;
		}
		else if(destination == 9)
		{
			Enqueue(source, destination, message, &nineHead, &nineTail, &nineFreeHead, &nineFreeTail, nine);
			nineSize++;
            return 0;
		}
		else if(destination == 10)
		{
			Enqueue(source, destination, message, &tenHead, &tenTail, &tenFreeHead, &tenFreeTail, ten);
			tenSize++;
            return 0;
		}
	}
	
	//return queue is full error
	else
		return -16;
}

int Retrieve(int destination)
{
	//dequeues message and returns the message to the testing interface
	if(hasMessage(destination) == 1)
	{
		if(destination == 1)
        {
            oneSize--;
			return Dequeue(&oneHead, &oneTail, &oneFreeHead, &oneFreeTail, one).message;
		}
        else if(destination == 2)
        {
            twoSize--;
			return Dequeue(&twoHead, &twoTail, &twoFreeHead, &twoFreeTail, two).message;
		}
        else if(destination == 3)
		{
            threeSize--;
            return Dequeue(&threeHead, &threeTail, &threeFreeHead, &threeFreeTail, three).message;
		}
        else if(destination == 4)
		{
            fourSize--;
            return Dequeue(&fourHead, &fourTail, &fourFreeHead, &fourFreeTail, four).message;
		}
        else if(destination == 5)
        {
            fiveSize--;
			return Dequeue(&fiveHead, &fiveTail, &fiveFreeHead, &fiveFreeTail, five).message;
		}
        else if(destination == 6)
        {
            sixSize--;
            return Dequeue(&sixHead, &sixTail, &sixFreeHead, &sixFreeTail, six).message;
		}
        else if(destination == 7)
		{
            sevenSize--;
            return Dequeue(&sevenHead, &sevenTail, &sevenFreeHead, &sevenFreeTail, seven).message;
		}
        else if(destination == 8)
		{
            eightSize--;
            return Dequeue(&eightHead, &eightTail, &eightFreeHead, &eightFreeTail, eight).message;
		}
        else if(destination == 9)
		{
            nineSize--;
            return Dequeue(&nineHead, &nineTail, &nineFreeHead, &nineFreeTail, nine).message;
		}
        else if(destination == 10)
		{
            tenSize--;
            return Dequeue(&tenHead, &tenTail, &tenFreeHead, &tenFreeTail, ten).message;
        }
    }
	
	//return empty queue error
	else
		return -15;
}